package middleware

import (
	"strings"

	"gitee.com/youkelike/ziam/zcode/zcode"
	"gitee.com/youkelike/ziam/zerrors"
	"gitee.com/youkelike/ziam/zutils/response"
	"github.com/gin-gonic/gin"
)

type AutoStrategy struct {
	basic AuthStrategy
	jwt   AuthStrategy
}

var _ AuthStrategy = &AutoStrategy{}

func NewAutoStrategy(basic, jwt AuthStrategy) AutoStrategy {
	return AutoStrategy{
		basic: basic,
		jwt:   jwt,
	}
}

func (a AutoStrategy) AuthFunc() gin.HandlerFunc {
	return func(c *gin.Context) {
		// factory := AuthFactory{}

		header := strings.SplitN(c.Request.Header.Get("Authorization"), " ", 2)
		if len(header) != 2 {
			response.Write(c, zerrors.WithCode(zcode.ErrSignatureInvalid, "Authorization header format is wrong."), nil)
			c.Abort()
			return
		}

		switch header[0] {
		case "Basic":
			// factory.SetStrategy(a.basic)
			a.basic.AuthFunc()(c)
		case "Bearer":
			// factory.SetStrategy(a.jwt)
			a.jwt.AuthFunc()(c)
		default:
			response.Write(c, zerrors.WithCode(zcode.ErrSignatureInvalid, "unrecognized Authorization header."), nil)
			c.Abort()
			return
		}

		// factory.AuthFunc()(c)

		c.Next()
	}
}

// 策略模式的实现，用在 auto 认证中
type AuthFactory struct {
	strategy AuthStrategy
}

func (f *AuthFactory) SetStrategy(s AuthStrategy) {
	f.strategy = s
}

func (f *AuthFactory) AuthFunc() gin.HandlerFunc {
	return f.strategy.AuthFunc()
}
